package com.xiangmo.travel.Service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xiangmo.travel.Dto.*;
import com.xiangmo.travel.Dvo.TableCollectDvo;
import com.xiangmo.travel.Dvo.TeamInfoDvo;
import com.xiangmo.travel.Dvo.TeamTapCountDvo;
import com.xiangmo.travel.Dvo.TeamUserDvo;
import com.xiangmo.travel.Entity.*;
import com.xiangmo.travel.Service.TeamService;
import com.xiangmo.travel.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Service
public class TeamServiceImpl implements TeamService {
    @Autowired
    private TeamMapper teamMapper;
    @Autowired
    private TeamUserMapper teamUserMapper;
    @Autowired
    private TeamRequestMapper teamRequestMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private NoticeMapper noticeMapper;

    @Override
    public int addTeam(TeamDto teamDto) {
        Team team = Team.builder()
                .attractionsId(teamDto.getAttractionsId())
                .description(teamDto.getDescription())
                .endTime(teamDto.getEndTime())
                .maxMembers(teamDto.getMaxMembers())
                .status(teamDto.getStatus())
                .title(teamDto.getTitle())
                .userId(teamDto.getUserId())
                .startingPoint(teamDto.getStartingPoint())
                .endPoint(teamDto.getEndPoint())
                .build();
        return teamMapper.insert(team);
    }

    @Override
    public int deleteTeam(Long id) {
        int status = 0;

        //删除成员表数据
        LambdaQueryWrapper<TeamUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TeamUser::getTeamId, id);
        Team team = teamMapper.selectById(id);
        List<TeamUser> list = teamUserMapper.selectList(lambdaQueryWrapper);
        for (TeamUser t : list){
            Notice notice = Notice.builder()
                    .receiveUserId(t.getUserId())
                    .sendUserId(team.getUserId())
                    .teamId(team.getId())
                    .content("您加入的队伍 <" + team.getTitle() + "> 已被队长解散，重新找一个吧~")
                    .title("队伍通知")
                    .confirm(0)
                    .build();
            noticeMapper.insert(notice);
        }
        //删除队伍表数据
        status += teamMapper.deleteById(id);
        status += teamUserMapper.delete(lambdaQueryWrapper);

        return status;
    }

    @Override
    public Page<Team> queryTeam(int pageNum, int pageSize, Long id) {
        Page<Team> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<Team> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Team::getAttractionsId, id)
                .and(i -> i.eq(Team::getStatus, 0))
                .and(i -> i.ge(Team::getEndTime, new Date()));
        return teamMapper.selectPage(page, lambdaQueryWrapper);
    }

    @Override
    public int changeTeamStatus(Long id) {
        return teamMapper.updateStatusById(1, id);
    }

    @Override
    public PageInfoDto<TeamInfoDvo<List<User>>> getMyTeamByUserId(Long userId, int pageNum, int pageSize) {
        LambdaQueryWrapper<Team> l = new LambdaQueryWrapper<>();
        l.eq(Team::getUserId, userId);
        Page<Team> pages = new Page<>(pageNum, pageSize);
        teamMapper.selectPage(pages, l);
        List<Team> teams = pages.getRecords();
        List<TeamInfoDvo<List<User>>> teamInfoDvoList = new ArrayList<>();
        for(Team team : teams){
            List<User> list = new ArrayList<>();
            //查询队长信息
            User user1 = userMapper.selectById(team.getUserId());
            list.add(user1);
            //查询队员信息
            LambdaQueryWrapper<TeamUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(TeamUser::getTeamId, team.getId());
            Page<TeamUser> page = new Page<>(1, team.getMaxMembers());
            teamUserMapper.selectPage(page, lambdaQueryWrapper);
            List<TeamUser> listTeamUser = new ArrayList<>();
            listTeamUser = page.getRecords();
            for(int i=0; i<page.getTotal(); i++){
                User user2 = userMapper.selectById(listTeamUser.get(i).getUserId());
                list.add(user2);
            }
            //封装
            TeamInfoDvo<List<User>> teamTeamInfoDvo = new TeamInfoDvo<>();
            teamTeamInfoDvo.setList(list);
            teamTeamInfoDvo.setTeamId(team.getId());
            teamTeamInfoDvo.setDescription(team.getDescription());
            teamTeamInfoDvo.setTitle(team.getTitle());
            teamTeamInfoDvo.setMaxMembers(team.getMaxMembers());
            teamTeamInfoDvo.setCreatedAt(team.getCreatedAt());
            teamTeamInfoDvo.setEndTime(team.getEndTime());
            teamTeamInfoDvo.setStatus(team.getStatus());
            teamTeamInfoDvo.setStartingPoint(team.getStartingPoint());
            teamTeamInfoDvo.setEndPoint(team.getEndPoint());
            teamTeamInfoDvo.setAttractionsId(team.getAttractionsId());
            teamInfoDvoList.add(teamTeamInfoDvo);
        }
        PageInfoDto<TeamInfoDvo<List<User>>> listPageInfoDto = new PageInfoDto<>();
        listPageInfoDto.setList(teamInfoDvoList);
        listPageInfoDto.setPageCurrent(pages.getCurrent());
        listPageInfoDto.setPages(pages.getPages());
        listPageInfoDto.setPageTotal(pages.getTotal());
        listPageInfoDto.setSize(pages.getSize());
        return listPageInfoDto;
    }

    @Override
    public User getTeamUserByTeamId(Long teamId) {
        Team team = teamMapper.selectById(teamId);
        return userMapper.selectById(team.getUserId());
    }

    @Override
    public Team getTeamByTeamId(Long teamId) {
        return teamMapper.selectById(teamId);
    }

    @Override
    public int addTeamUser(TeamUserDto teamUserDto) {
        TeamUser teamUser = TeamUser.builder()
                .teamId(teamUserDto.getTeamId())
                .userId(teamUserDto.getUserId())
                .build();
        return teamUserMapper.insert(teamUser);
    }

    @Override
    public int deleteTeamUser(Long userId, Long teamId) {
        LambdaQueryWrapper<TeamUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TeamUser::getUserId, userId)
                .eq(TeamUser::getTeamId, teamId);
        return teamUserMapper.delete(lambdaQueryWrapper);
    }

    //需要把队长也加上去
    @Override
    public List<TeamUserDvo> queryTeamUser(Long teamId) {
        LambdaQueryWrapper<TeamUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TeamUser::getTeamId, teamId);
        List<TeamUser> list = teamUserMapper.selectList(lambdaQueryWrapper);
        //封装队长的信息
        LambdaQueryWrapper<Team> lambdaQueryWrappers = new LambdaQueryWrapper<>();
        lambdaQueryWrappers.eq(Team::getId, teamId);
        Team team = teamMapper.selectOne(lambdaQueryWrappers);
        List<TeamUserDvo> teamUserDvoList = new ArrayList<>();
        TeamUserDvo teamUserDvos = new TeamUserDvo();
        Long teamCounts = this.getTeamCountByUserId(team.getUserId());
        teamUserDvos.setTeamId(team.getId());
        teamUserDvos.setTeamCount(teamCounts);
        teamUserDvos.setUserId(team.getUserId());
        teamUserDvoList.add(teamUserDvos);
        //封装成员的信息
        for(TeamUser t : list){
            TeamUserDvo teamUserDvo = new TeamUserDvo();
            Long teamCount = this.getTeamCountByUserId(t.getUserId());
            teamUserDvo.setTeamId(t.getTeamId());
            teamUserDvo.setTeamCount(teamCount);
            teamUserDvo.setUserId(t.getUserId());
            teamUserDvo.setJoinTime(t.getJoinTime());
            teamUserDvo.setId(t.getId());
            teamUserDvoList.add(teamUserDvo);
        }
        return teamUserDvoList;
    }

    /**
     * 判断是队长的操作还是队员的操作
     */
    @Override
    public int checkTeamUserRoot(TeamUserDto teamUserDto, Long tokenUserId) {
        //本人要修改本人的记录
        if(Objects.equals(teamUserDto.getUserId(), tokenUserId)){
            return 1;
        }
        //根据队id查询队长id
        Team team = teamMapper.selectUserIdById(teamUserDto.getTeamId());
        if(Objects.equals(team.getUserId(), tokenUserId)){
            return 2;
        }
        return 0;
    }

    @Override
    public PageInfoDto<TeamInfoDvo<List<User>>> getOtherTeamByUserId(Long userId, int pageNum, int pageSize) {
        LambdaQueryWrapper<TeamUser> lambdaQueryWrappers = new LambdaQueryWrapper<>();
        lambdaQueryWrappers.eq(TeamUser::getUserId, userId);
        Page<TeamUser> pages = new Page<>(pageNum, pageSize);
        teamUserMapper.selectPage(pages, lambdaQueryWrappers);
        List<TeamUser> listTeamUser = new ArrayList<>();
        listTeamUser = pages.getRecords();
        List<TeamInfoDvo<List<User>>> teamInfoDvoList = new ArrayList<>();
        for(TeamUser teamUser : listTeamUser){
            Team team = teamMapper.selectById(teamUser.getTeamId());

            List<User> list = new ArrayList<>();
            //查询队长信息
            User user1 = userMapper.selectById(team.getUserId());
            list.add(user1);
            //查询队员信息
            LambdaQueryWrapper<TeamUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(TeamUser::getTeamId, team.getId());
            Page<TeamUser> page = new Page<>(1, team.getMaxMembers());
            teamUserMapper.selectPage(page, lambdaQueryWrapper);
            List<TeamUser> listTeamUsers = new ArrayList<>();
            listTeamUsers = page.getRecords();
            for(int i=0; i<page.getTotal(); i++){
                User user2 = userMapper.selectById(listTeamUsers.get(i).getUserId());
                list.add(user2);
            }
            //封装
            TeamInfoDvo<List<User>> teamTeamInfoDvo = new TeamInfoDvo<>();
            teamTeamInfoDvo.setList(list);
            teamTeamInfoDvo.setTeamId(team.getId());
            teamTeamInfoDvo.setDescription(team.getDescription());
            teamTeamInfoDvo.setTitle(team.getTitle());
            teamTeamInfoDvo.setMaxMembers(team.getMaxMembers());
            teamTeamInfoDvo.setCreatedAt(team.getCreatedAt());
            teamTeamInfoDvo.setEndTime(team.getEndTime());
            teamTeamInfoDvo.setStatus(team.getStatus());
            teamTeamInfoDvo.setStartingPoint(team.getStartingPoint());
            teamTeamInfoDvo.setEndPoint(team.getEndPoint());
            teamTeamInfoDvo.setAttractionsId(team.getAttractionsId());
            teamInfoDvoList.add(teamTeamInfoDvo);
        }
        PageInfoDto<TeamInfoDvo<List<User>>> listPageInfoDto = new PageInfoDto<>();
        listPageInfoDto.setList(teamInfoDvoList);
        listPageInfoDto.setPageCurrent(pages.getCurrent());
        listPageInfoDto.setPages(pages.getPages());
        listPageInfoDto.setPageTotal(pages.getTotal());
        listPageInfoDto.setSize(pages.getSize());
        return listPageInfoDto;
    }

    @Override
    public int addTeamRequest(TeamRequestDto teamRequestDto) {
        TeamRequest teamRequest = TeamRequest.builder()
                .teamId(teamRequestDto.getTeamId())
                .userId(teamRequestDto.getUserId())
                .tell(teamRequestDto.getTell())
                .status(teamRequestDto.getStatus())
                .build();
        return teamRequestMapper.insert(teamRequest);
    }

    @Override
    public Page<TeamRequest> queryTeamRequest(int pageNum, int pageSize, Long teamId) {
        Page<TeamRequest> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<TeamRequest> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(TeamRequest::getTeamId, teamId);
        return teamRequestMapper.selectPage(page, lambdaQueryWrapper);
    }

    @Override
    public int deleteTeamRequest(Long id) {
        return teamRequestMapper.deleteById(id);
    }

    @Override
    public int checkTeamRequestRoot(TeamRequestDto teamRequestDto, Long userId) {
        //本人要修改本人的记录
        if(Objects.equals(teamRequestDto.getUserId(), userId)){
            return 1;
        }
        return 0;
    }

    @Override
    public int checkTeamByUserIdAndAttractionsId(Long userId, Long attractionsId) {
        LambdaQueryWrapper<Team> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Team::getAttractionsId, attractionsId)
                .eq(Team::getUserId, userId)
                .eq(Team::getStatus, 0);
        if(teamMapper.selectCount(lambdaQueryWrapper) > 0){
            return 1;
        }
        return 0;
    }

    @Override
    public int checkTeamUserByUserIdAndTeamId(Long userId, Long teamId) {
        if(teamUserMapper.selectAllByTeamIdAndUserId(teamId, userId) != null){
            return 1;
        }
        return 0;
    }

    @Override
    public int checkTeamRequestByUserIdAndTeamId(Long userId, Long teamId) {
        if(teamRequestMapper.selectAllByTeamIdAndUserId(teamId, userId) != null){
            return 1;
        }
        return 0;
    }

    @Override
    // 定义一个方法，用于查询前十三名用户的组队次数排名
    public List<TeamTapCountDvo> getTopTenRanking() {
        //封装 --- 以后有空写个数据封装的框架
        List<TeamTapCountDto> teamTapCountDto = teamMapper.selectTop10UserByTeamCount();
        List<TeamTapCountDvo> result = new ArrayList<>();
        for(TeamTapCountDto t : teamTapCountDto){
            TeamTapCountDvo teamTapCountDvo = new TeamTapCountDvo();
            User user = userMapper.selectById(t.getUserId());
            teamTapCountDvo.setName(user.getName());
            teamTapCountDvo.setTotal(t.getTotal());
            teamTapCountDvo.setUserId(user.getId());
            teamTapCountDvo.setUserIcon(user.getImage());
            result.add(teamTapCountDvo);
        }
        return result;
    }

    @Override
    public List<TableCollectDvo> getTop6TeamById(Long id) {
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        // 获取六天前的时间
        LocalDateTime sixDaysBefore = now.minusDays(6);
        // 构建查询条件
        QueryWrapper<Team> wrapper = new QueryWrapper<>();
        wrapper.select("DATE(created_at) as created_at", "count(*) as count")
                .eq("attractions_id", id)
                .between("created_at", sixDaysBefore, now)
                .groupBy("DATE(created_at)")
                .orderByDesc("created_at");
        // 执行查询
        List<Map<String, Object>> result = teamMapper.selectMaps(wrapper);
        // 封装结果
        List<TableCollectDvo> vos = new ArrayList<>();
        for (int i = 0; i < 6; i++) {
            TableCollectDvo vo = new TableCollectDvo();
            LocalDate currentDate = LocalDate.now().minusDays(i);
            vo.setCreatedAt(currentDate.toString());
            vo.setCount(0L);
            for (Map<String, Object> map : result) {
                LocalDate dateInMap = ((java.sql.Date) map.get("created_at")).toLocalDate();
                if (currentDate.equals(dateInMap)) {
                    vo.setCount((Long) map.get("count"));
                    break;
                }
            }
            vos.add(vo);
        }
        return vos;
    }

    //根据用户id查询该用户的组队次数
    @Override
    public Long getTeamCountByUserId(Long userId) {
        LambdaQueryWrapper<Team> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Team::getUserId, userId);
        LambdaQueryWrapper<TeamUser> lambdaQueryWrappers = new LambdaQueryWrapper<>();
        lambdaQueryWrappers.eq(TeamUser::getUserId, userId);
        Long count1 = teamMapper.selectCount(lambdaQueryWrapper);
        Long count2 = teamUserMapper.selectCount(lambdaQueryWrappers);
        return count1 + count2;
    }
}
